package com.lanou3g.ptp.teacher.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lanou3g.ptp.base.service.BaseService;
import com.lanou3g.ptp.entity.*;
import com.lanou3g.ptp.organize.service.CollegeService;
import com.lanou3g.ptp.organize.service.MajorService;
import com.lanou3g.ptp.organize.service.SchoolService;
import com.lanou3g.ptp.taskrole.service.TaskRoleService;
import com.lanou3g.ptp.teacher.mapper.RoleTeacherMapper;
import com.lanou3g.ptp.teacher.mapper.TeacherMapper;
import com.lanou3g.ptp.teacher.service.TeacherService;
import com.lanou3g.ptp.user.service.UserService;
import com.lanou3g.ptp.utils.ExcelUtils;
import com.lanou3g.ptp.vo.Option;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFCreationHelper;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service(timeout = 10000)
public class TeacherServiceImpl implements TeacherService {

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private RoleTeacherMapper roleTeacherMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Reference
    private TaskRoleService taskRoleService;

    @Reference(lazy = true)
    private SchoolService schoolService;

    @Reference(lazy = true)
    private CollegeService collegeService;

    @Reference(lazy = true)
    private MajorService majorService;

    @Reference(lazy = true)
    private UserService userService;

    @Reference(lazy = true)
    private BaseService baseService;

    @Value("${REDIS_TEACHER_KEY_PREFIX}")
    private String REDIS_TEACHER_KEY_PREFIX;

    @Value("${REDIS_TEACHER_KEY_EXPIRE}")
    private String REDIS_TEACHER_KEY_EXPIRE;

    private String no = "工号";
    private String name = "姓名";
    private String tel = "手机号";
    private String teacherType = "教师类型";
    private String[] teacherTypes = new String[]{"校内", "校外"};
    private String major = "专业";
    private String teachsection = "教研室";
    private String base = "基地";
    private List<String> columns = Arrays.asList(no, name, tel, teacherType, major, teachsection, base);
    private int noIndex = columns.indexOf(no);
    private int nameIndex = columns.indexOf(name);
    private int telIndex = columns.indexOf(tel);
    private int teacherTypeIndex = columns.indexOf(teacherType);
    private int majorIndex = columns.indexOf(major);
    private int teachsectionIndex = columns.indexOf(teachsection);
    private int baseIndex = columns.indexOf(base);
    private int cols = columns.size();
    private int max = 300;

    // 添加教师
    @Override
    public int insert(Teacher teacher) {
        Date date = new Date();
        User user = teacher.getUser();
        user.setStatus(0);
        user.setCreateTime(date);
        user.setUpdateTime(date);
        //创建用户
        Long id;
        try {
            id = userService.addUser(user);
        } catch (Exception e) {
            return 0;
        }
        //创建教师
        if (id != null) {
            teacher.setId(id);
            Long collegeId = teacher.getCollegeId();
            RoleTeacher roleTeacher = new RoleTeacher();
            if (collegeId != null) {
                if (teacher.getSchoolId() == null) {
                    College college = collegeService.findById(collegeId);
                    teacher.setSchoolId(college.getSchoolId());
                }
                teacher.setType(0);
                roleTeacher.setRoleId(Role.ROLE_SCHOOL_TEACHER);
            } else {
                teacher.setType(1);
                roleTeacher.setRoleId(Role.ROLE_BASE_TEACHER);
            }
            // 创建角色信息
            roleTeacher.setTeacherId(id);
            try {
                roleTeacherMapper.addRoleTeacher(roleTeacher);
            } catch (Exception e) {
                return 0;
            }
            teacher.setStatus(0);
            teacher.setCreateTime(date);
            teacher.setUpdateTime(date);
            return teacherMapper.add(teacher);
        }
        return 0;
    }

    // 查询所有教师
    @Override
    public PageInfo<Teacher> findAll(Integer page, Integer size) {

        PageHelper.startPage(page, size);
        List<Teacher> teacherList = teacherMapper.search();
        completeTeacherList(teacherList);
        return new PageInfo<>(teacherList);

    }

    private void completeTeacherList(List<Teacher> teacherList) {
        for (Teacher teacher : teacherList) {
            User user = userService.userById(teacher.getId());
            user.setPassword(null);
            teacher.setUser(user);
            if (teacher.getType() == 0) {// 本校
                Long collegeId = teacher.getCollegeId();
                Long majorId = teacher.getMajorId();
                College college = collegeService.findById(collegeId);
                teacher.setCollegeName(college.getName());
                if (majorId != null) {
                    Major major = majorService.findById(majorId);
                    teacher.setMajorName(major.getName());
                }
            } else {// 校外
                Base base = baseService.findById(teacher.getBaseId());
                teacher.setBaseName(base.getName());
            }
        }
    }

    // 通过id查询教师
    @Override
    public Teacher findById(Long id) {

        // 设置key
        String s1 = REDIS_TEACHER_KEY_PREFIX + id;
        // 根据key，查询redis中是否存在数据
        String s2 = redisTemplate.opsForValue().get(s1);
        if (s2 == null) {
            // 通过id查询教师
            Teacher teacher = teacherMapper.findById(id);
            // 将查询到的Teacher对象序列化为JSON字符串
            String s = JSON.toJSONString(teacher);
            redisTemplate.opsForValue().set(s1, s, 10, TimeUnit.SECONDS);
            return teacher;
        } else {
            // redis中存在数据，刷新过期时间
            redisTemplate.expire(s1, 10, TimeUnit.SECONDS);
            // 返回对象
            return JSON.parseObject(s2, Teacher.class);
        }

    }

    // 根据名字查询教师
    @Override
    public PageInfo<Teacher> findByKeyword(Integer page, Integer size, String keyword) {
        PageHelper.startPage(page, size);
        List<Teacher> list = new ArrayList<>();
        List<User> users = userService.userByName("%" + keyword + "%");
        for (User user : users) {
            Teacher teacher = teacherMapper.findById(user.getId());
            teacher.setUser(user);
            list.add(teacher);
        }
        return new PageInfo<>(list);
    }

    // 通过id删除教师
    @Override
    public void deleteById(Long id) {
        int i = userService.deleteById(id);
//        if (i > 0) {
//            teacherMapper.minus(id);
//        }
    }

    // 通过id更改
    @Override
    public boolean updateById(Teacher teacher) {
        Date date = new Date();
        teacher.setUpdateTime(date);
        int i = teacherMapper.update(teacher);
        try {
            User user = teacher.getUser();
            user.setUpdateTime(date);
            int j = userService.upUser(user);
            return i > 0 || j > 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    // 通过id批量删除
    @Override
    public void deleteByIds(Long[] ids) {
        for (Long aLong : ids) {
            int i = userService.deleteById(aLong);
//            if (i > 0) {
//                teacherMapper.deleteByIds(ids);
//            }
        }
    }

    // 生成Excel表格
    @Override
    public void excelPoi(List<Teacher> teachers) {

        //try {
        // 创建一个sheet
        HSSFWorkbook sheets = new HSSFWorkbook();
        Sheet sheet = sheets.createSheet("sheet1");
        int i = 1;

        Row roww = sheet.createRow(0);
        sheet.setColumnWidth(0, 25 * 256);
        sheet.setColumnWidth(1, 30 * 256);
        sheet.setColumnWidth(2, 30 * 256);
        sheet.setColumnWidth(3, 30 * 256);
        sheet.setColumnWidth(4, 30 * 256);
        // 设置行的高度
        roww.setHeightInPoints(30);
        roww.createCell(0).setCellValue("id");
        roww.createCell(1).setCellValue("姓名");
        roww.createCell(2).setCellValue("性别");
        roww.createCell(3).setCellValue("手机号");
        roww.createCell(4).setCellValue("教师类型");


        // 遍历teacher，给teacher的User属性赋值
        for (Teacher teacher : teachers) {
            User user = userService.userById(teacher.getId());
            teacher.setUser(user);
        }

        for (Teacher teacher : teachers) {

            Row row = sheet.createRow(i);
            sheet.setColumnWidth(0, 25 * 256);
            sheet.setColumnWidth(1, 30 * 256);
            sheet.setColumnWidth(2, 30 * 256);
            sheet.setColumnWidth(3, 30 * 256);
            sheet.setColumnWidth(4, 30 * 256);
            // 设置行的高度
            row.setHeightInPoints(30);

            HSSFCreationHelper creationHelper = sheets.getCreationHelper();

            /*设置单元格样式*/

            // 单元格对齐方式
            HSSFCellStyle cellStyle = sheets.createCellStyle();
            // 水平对齐居中
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            // 垂直居中
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            // 设置字体样式风格
            HSSFCellStyle cellStyle1 = sheets.createCellStyle();
            // 创建字体样式
            HSSFFont font = sheets.createFont();
            // 设置字体样式
            font.setFontName("仿宋");
            // 设置字号
            font.setFontHeightInPoints((short) 16);
            // 设置字体颜色
            font.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
            // 将字体样式放入cellStyle1
            cellStyle1.setFont(font);

            if (i != 0) {
                // id
                Cell cell = row.createCell(0);
                cell.setCellValue(teacher.getId());
                cell.setCellStyle(cellStyle);
                cell.setCellStyle(cellStyle1);

                // 姓名
                Cell cell1 = row.createCell(1);
                cell1.setCellValue(teacher.getUser().getName());
                cell1.setCellStyle(cellStyle);
                cell1.setCellStyle(cellStyle1);

                // 性别
//                Cell cell2 = row.createCell(2);
//                String string = null;
//                if (teacher.getGender() == 0) {
//                    string = "男";
//                } else {
//                    string = "女";
//                }
//                cell2.setCellValue(string);
//                cell2.setCellStyle(cellStyle);
//                cell2.setCellStyle(cellStyle1);

                // 手机号
                Cell cell3 = row.createCell(3);
                cell3.setCellValue(teacher.getUser().getTel());
                cell3.setCellStyle(cellStyle);
                cell3.setCellStyle(cellStyle1);

                // 教师类型
                Cell cell4 = row.createCell(4);
                String str = null;

                if (teacher.getType() == 0) {
                    str = "本校教师";
                } else {
                    str = "校外教师";
                }

                cell4.setCellValue(str);
                cell4.setCellStyle(cellStyle);
                cell4.setCellStyle(cellStyle1);

            }
            i++;
        }


        // 设置Excel表格存储路径
        FileOutputStream stream = null;
        try {
            stream = new FileOutputStream("D:\\用户信息表1.xls");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            sheets.write(stream);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    // 导出Excel
    @Override
    public List<Teacher> getData(Long[] ids) {

        List<Teacher> teacherList = null;

        if (ids != null) {
            teacherList = teacherMapper.getData(ids);
            excelPoi(teacherList);
        } else {
            teacherList = teacherMapper.search();
            excelPoi(teacherList);
        }

        return teacherList;
    }


    // 解析导入老师
    @Override
    public int excelToTeacherInfo(byte[] bytes) {
        int count = 0;

        InputStream teacherUploadFile = new ByteArrayInputStream(bytes);

//        List<Teacher> teachers = new ArrayList<>();

        try {
            XSSFWorkbook wb = new XSSFWorkbook(teacherUploadFile);

            XSSFSheet sheet = wb.getSheetAt(0);

            if (sheet != null) {
                XSSFCell collegeIdCell = sheet.getRow(max).getCell(cols + 2);
                String collegeIdCellValue = collegeIdCell.getRawValue();
                if (collegeIdCellValue == null) {
                    return count;
                }
                Long collegeId = Long.parseLong(collegeIdCellValue);
                College college = collegeService.findById(collegeId);

                // rowNum从第2行开始循环,排除表头
                for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {

                    Row row = sheet.getRow(rowNum);

                    // 将循环得到的信息存储到对象中
                    Teacher teacher = new Teacher();
                    User user = new User();
                    teacher.setUser(user);

                    String noExcel = ExcelUtils.getCellValue(row.getCell(noIndex));
                    user.setNo(noExcel);

                    String nameExcel = ExcelUtils.getCellValue(row.getCell(nameIndex));
                    user.setName(nameExcel);

                    String telExcel = ExcelUtils.getCellValue(row.getCell(telIndex));
                    user.setTel(telExcel);

                    String typeExcel = ExcelUtils.getCellValue(row.getCell(teacherTypeIndex));
                    if (teacherTypes[0].equals(typeExcel)) {
                        teacher.setType(0);
                        teacher.setSchoolId(college.getSchoolId());
                        teacher.setCollegeId(collegeId);

                        String majorExcel = ExcelUtils.getCellValue(row.getCell(majorIndex));
                        if (majorExcel != null) {
                            Long majorId = majorService.findByName(collegeId, majorExcel).getId();
                            teacher.setMajorId(majorId);
                        }
                        String teachSectionExcel = ExcelUtils.getCellValue(row.getCell(teachsectionIndex));
                        if (teachSectionExcel != null) {
                            teacher.setTeachsection(teachSectionExcel);
                        }
                    } else if (teacherTypes[1].equals(typeExcel)) {
                        teacher.setType(1);
                        String baseExcel = ExcelUtils.getCellValue(row.getCell(baseIndex));
                        List<Base> bases = baseService.findByName(baseExcel);
                        if (bases.size() > 0) {
                            teacher.setBaseId(bases.get(0).getId());
                        }
                    } else {
                        continue;
                    }
                    count += insert(teacher);
                }
                return count;
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return count;
        }
    }

    @Override
    public boolean teacherExcel(List<Teacher> teachers) {

        // 记录 加入条数总数
        int sum = 0;
        boolean b = false;
        // 加入数据
        for (Teacher teacher : teachers) {
            insert(teacher);
        }
        // 判定是否加入条数和信息总数一直  返回结果
        if (sum == teachers.size()) {
            b = true;
        }
        return b;
    }

    @Override
    public List<Long> findByTaskId(Long taskId) {
        List<TaskRole> taskRoles = taskRoleService.findByTaskId(taskId);
        List<Long> roleIds = new ArrayList<>();
        List<Long> teacherIds = new ArrayList<>();
        List<Long> teacherIds1 = new ArrayList<>();
        for (TaskRole taskRole : taskRoles) {
            Long roleId = taskRole.getRoleId();
            roleIds.add(roleId);
        }
        System.out.println(roleIds + ";;;");
        for (Long roleId : roleIds) {
            List<RoleTeacher> roleTeachers = roleTeacherMapper.findByRoleId(roleId);
            for (RoleTeacher roleTeacher : roleTeachers) {
                Long teacherId = roleTeacher.getTeacherId();
                teacherIds.add(teacherId);
            }
        }
        for (Long teacherId : teacherIds) {
            List<Teacher> teachers = teacherMapper.findByIdAndType(teacherId);
            for (Teacher teacher : teachers) {
                Long id = teacher.getId();
                teacherIds1.add(id);
            }
        }
        return teacherIds1;
    }

    @Override
    public List<Teacher> findByIdAndType(Long teacherId) {
        List<Teacher> teachers = teacherMapper.findByIdAndType(teacherId);
        return teachers;
    }

    @Override
    public List<Teacher> findByCollegeId(Long collegeId) {
        return teacherMapper.findByCollegeId(collegeId);
    }

    @Override
    public List<Teacher> findByMajorId(Long majorId) {
        return teacherMapper.findByMajorId(majorId);
    }

    @Override
    public PageInfo<Teacher> findBySchoolId(Long schoolId, Integer page, Integer size) {
        PageHelper.startPage(page, size);
        List<Teacher> teacherList = teacherMapper.findBySchoolId(schoolId);
//        completeTeacherList(teacherList);
        return new PageInfo<>(teacherList);
    }

    @Override
    public List<Option> optionsByBaseId(Long baseId) {
        return this.teacherMapper.optionsByBaseId(baseId);
    }

    @Override
    public List<Option> optionsByTeachlinkId(Long teachlinkId) {
        return this.teacherMapper.optionsByTeachlinkId(teachlinkId);
    }

    @Override
    public byte[] getInfoModelExcelByCollegeId(Long collegeId) {
//        String teacherType = "教师类型";
//        String[] teacherTypes = new String[]{"校内", "校外"};
//        String major = "专业";
        String[] majors = majorService.findNamesByCollegeId(collegeId);
//        String base = "基地";
        String[] bases = baseService.findNames();
//        List<String> columns = Arrays.asList("工号", "姓名", "手机号", teacherType, major, "教研室", base);
//        int teacherTypeIndex = columns.indexOf(teacherType);
//        int majorIndex = columns.indexOf(major);
//        int baseIndex = columns.indexOf(base);
//        int cols = columns.size();
//        int max = 300;

        // 创建一个新的工作簿
        XSSFWorkbook sheets = new XSSFWorkbook();
        XSSFSheet sheet = sheets.createSheet("教师信息");
        sheet.setZoom(140);

        // 创建表头
        Row row0 = sheet.createRow(0);
        row0.setHeightInPoints(20);

        // 设置表头值
        for (int i = 0; i < cols; i++) {
            String column = columns.get(i);
            row0.createCell(i).setCellValue(column);
            if (teacherType.equals(column)) {
                XSSFDrawing drawingPatriarch = sheet.createDrawingPatriarch();
                XSSFComment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0,
                        (short) 6, 2, (short) 12, 8));
                comment.setString("可用值（校内、校外）\n" +
                        "校内教师必须填写学院，专业和教研室为选填；\n" +
                        "校外教师必须填写基地。");
                row0.getCell(i).setCellComment(comment);
            }
        }

        // 负责表格对齐方式
        XSSFCellStyle cellStyle0 = sheets.createCellStyle();
        // 设置单元格水平方向对齐方式居中
        cellStyle0.setAlignment(HorizontalAlignment.CENTER);
        // 设置单元格垂直方向对齐方式居中
        cellStyle0.setVerticalAlignment(VerticalAlignment.CENTER);
        // 边框
        cellStyle0.setBorderTop(BorderStyle.THIN);
        cellStyle0.setBorderRight(BorderStyle.THIN);
        cellStyle0.setBorderBottom(BorderStyle.THIN);
        cellStyle0.setBorderLeft(BorderStyle.THIN);

        cellStyle0.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        cellStyle0.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        // 设置字体样式
        XSSFFont font0 = sheets.createFont();
        font0.setFontName("微软雅黑");
        // 设置字号
        font0.setFontHeightInPoints((short) 12);
        font0.setBold(true);
        // 设置字体颜色
//        font0.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex());
        // 字体风格放入风格
        cellStyle0.setFont(font0);

        for (int i = 0; i < cols; i++) {
            sheet.setColumnWidth(i, 17 * 256);
            row0.getCell(i).setCellStyle(cellStyle0);
        }

        ////////////内容
        XSSFCellStyle cellStyle = sheets.createCellStyle();
        // 边框
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);

        // 设置字体样式
        XSSFFont font = sheets.createFont();
        font.setFontName("微软雅黑");
        // 字体风格放入风格
        cellStyle.setFont(font);

        for (int i = 1; i <= max; i++) {
            Row row = sheet.createRow(i);
//        Cell column = row0.getCell(j);
            for (int j = 0; j < cols; j++) {
                Cell cell = row.createCell(j);
                cell.setCellStyle(cellStyle);

            }
        }

        // 四个参数依次的意思是：开始行，结束行，开始列，结束列 此处表示sheet页中的第一个单元格
        CellRangeAddressList teacherTypeRange = new CellRangeAddressList(1, max, teacherTypeIndex, teacherTypeIndex);
        // 创建一个列表约束
        XSSFDataValidationConstraint teacherTypeVC = new XSSFDataValidationConstraint(teacherTypes);
        // 创建一个数据的有效性
        DataValidation teacherTypeDV =
                new XSSFDataValidationHelper(sheet).createValidation(teacherTypeVC, teacherTypeRange);
        teacherTypeDV.setSuppressDropDownArrow(true);
        teacherTypeDV.setShowErrorBox(true);
        sheet.addValidationData(teacherTypeDV);

        CellRangeAddressList majorRange = new CellRangeAddressList(1, max, majorIndex, majorIndex);
        XSSFDataValidationConstraint majorVC = new XSSFDataValidationConstraint(majors);
        DataValidation majorDV = new XSSFDataValidationHelper(sheet).createValidation(majorVC, majorRange);
        majorDV.setSuppressDropDownArrow(true);
        majorDV.setShowErrorBox(true);
        sheet.addValidationData(majorDV);

        CellRangeAddressList baseRange = new CellRangeAddressList(1, max, baseIndex, baseIndex);
        XSSFDataValidationConstraint baseVC = new XSSFDataValidationConstraint(bases);
        DataValidation baseDV = new XSSFDataValidationHelper(sheet).createValidation(baseVC, baseRange);
        baseDV.setSuppressDropDownArrow(true);
        baseDV.setShowErrorBox(true);
        sheet.addValidationData(baseDV);

        // 设置collegeId，方便导入数据
        XSSFCell collegeIdCell = sheet.getRow(max).createCell(cols + 2);
        collegeIdCell.setCellValue(collegeId);
//        XSSFCellStyle collegeIdCellStyle = sheets.createCellStyle();
//        collegeIdCellStyle.setHidden(true);
//        collegeIdCell.setCellStyle(collegeIdCellStyle);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            sheets.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return outputStream.toByteArray();
    }

    @Override
    public List<Option> optionsByMajorId(Long majorId) {
        return this.teacherMapper.optionsByMajorId(majorId);
    }

    @Override
    public boolean enable(Long teacherId) {
        Teacher teacher = new Teacher();
        teacher.setId(teacherId);
        teacher.setStatus(0);
        return updateById(teacher);
    }

    @Override
    public boolean disable(Long teacherId) {
        Teacher teacher = new Teacher();
        teacher.setId(teacherId);
        teacher.setStatus(1);
        return updateById(teacher);
    }

}
